package com.hbnu.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbnu.system.config.BaseException;
import com.hbnu.system.constant.AuthorTypeConstants;
import com.hbnu.system.mapper.WorkauthorMapper;
import com.hbnu.system.model.entity.Paperauthor;
import com.hbnu.system.model.entity.User;
import com.hbnu.system.model.entity.Work;
import com.hbnu.system.model.entity.Workauthor;
import com.hbnu.system.service.IUserService;
import com.hbnu.system.service.IWorkQualificationService;
import com.hbnu.system.service.IWorkService;
import com.hbnu.system.service.IWorkauthorService;
import com.hbnu.system.utils.CheckRoleUtil;
import com.hbnu.system.utils.IdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 著作作者服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2023-05-16
 */
@Service
public class WorkauthorServiceImpl extends ServiceImpl<WorkauthorMapper, Workauthor> implements IWorkauthorService {

    @Autowired
    private IWorkService iWorkService;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private CheckRoleUtil checkRoleUtil;

    @Autowired
    private IWorkQualificationService iWorkQualificationService;

    private static final List<String> AUTHOR_TYPE_ORDER = Arrays.asList(
            "第一作者", "共同第一作者", "通讯作者", "第二作者", "第三作者", "其他排名"
    );

    // 用于保留两位小数的格式化器
    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00");

    /**
     * 添加著作作者
     * @param workauthor 著作作者信息
     * @return 添加操作是否成功
     */
    @Override
    public boolean addWorkAuthor(Workauthor workauthor) {
        //不使用前端传过来的id，而是生成一个新的id
        workauthor.setWorkAuthorID(null);
        //检查权限
        Work work = iWorkService.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID, workauthor.getWorkID()));
        checkRoleUtil.checkPermissionAchievement(work.getStatus());

        //如果是校外作者或者学生，为其生成工号
        if (workauthor.getPeopleType().equals(AuthorTypeConstants.OUT_SCHOOL_AUTHOR)
                ||workauthor.getPeopleType().equals(AuthorTypeConstants.STUDENT)) {
            workauthor.setUserAccount(IdGenerator.generateId());
        }

        if (StrUtil.isEmpty(workauthor.getUserAccount())) {
            throw new BaseException("请输入工号");
        }

        //检查作者是否已经存在
        Workauthor existingAuthor = getOne(Wrappers.lambdaQuery(Workauthor.class)
                .eq(Workauthor::getWorkID, workauthor.getWorkID())
                .eq(Workauthor::getUserAccount, workauthor.getUserAccount()));
        if (Objects.nonNull(existingAuthor)) {
            throw new BaseException("不可重复添加");
        }

        //判断分数是否合法
        double newAssessment;
        try {
            newAssessment = Double.parseDouble(workauthor.getAssessment());
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0 - 100范围内");
        }

        String Pscore = "0.00";

        if(work != null){
            float finalValue = work.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }

        //检查是否超过100分
        List<Workauthor> workauthorList = list(Wrappers.lambdaQuery(Workauthor.class)
                .eq(Workauthor::getWorkID, workauthor.getWorkID()));
        double sum = 0;
        for (Workauthor author : workauthorList) {
            if(author.getAssessment().equals("")){
                throw new BaseException("请补全所有作者考核系数");
            }
            sum += Double.parseDouble(author.getAssessment());
        }
        if (sum + newAssessment > 100) {
            throw new BaseException("作者考核系数总和大于100!");
        }

        workauthor.setPscore(Pscore);

        //检查是否为第一作者，如果是，检查是否已经存在第一作者
        if ("第一作者".equals(workauthor.getAuthortype())) {
            for (Workauthor author : workauthorList) {
                if ("第一作者".equals(author.getAuthortype())) {
                    throw new BaseException("该著作已存在第一作者!");
                }
            }
        }

        //插入作者信息
        save(workauthor);

        //维护AllAuthor字段
        updateAllAuthor(work, workauthor);
        return true;
    }

    /**
     * 查询著作的作者
     * @param id 著作ID
     * @return 著作作者列表
     */
    @Override
    public List<Workauthor> pageworkauthor(String id) {
        List<Workauthor> list = baseMapper.selectList(Wrappers.lambdaQuery(Workauthor.class)
                .eq(Workauthor::getWorkID, id));
        list.sort(Comparator.comparingInt(p -> AUTHOR_TYPE_ORDER.indexOf(p.getAuthortype())));
        return list;
    }

    /**
     * 修改著作作者
     *
     * @param workauthor
     * @return
     */
    @Override
    public boolean upWorkAuthor(Workauthor workauthor) {
        Work work = iWorkService.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID, workauthor.getWorkID()));
        checkRoleUtil.checkPermissionAchievement(work.getStatus());
        double newAssessment;
        try {
            newAssessment = Double.parseDouble(workauthor.getAssessment());
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0 - 100范围内");
        }
//        int Pscore = Integer.parseInt(workauthor.getPscore());
        String Pscore = "0.00";

        if(work != null){
            float finalValue = work.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }
        List<Workauthor> workauthorList = query().eq("WorkID", workauthor.getWorkID()).list();
        double sum = 0;
        for (Workauthor author : workauthorList) {
            if (!author.getWorkAuthorID().equals(workauthor.getWorkAuthorID())) {
                if(author.getAssessment().equals("")){
                    throw new BaseException("请补全所有作者考核系数");
                }
                sum += Double.parseDouble(author.getAssessment());
            }
        }
        if (sum + newAssessment > 100) {
            throw new BaseException("该著作的作者考核系数和超过100");
        }

        workauthor.setPscore(Pscore);

        baseMapper.updateById(workauthor);

        //维护AllAuthor字段
        updateAllAuthor(work, workauthor);

        return true;
    }

    /**
     * 删除著作作者
     * @param id 作者ID
     * @return 删除操作是否成功
     */
    @Override
    public boolean deleteWorkAuthor(String id) {

        Workauthor workauthor = super.getOne(Wrappers.lambdaQuery(Workauthor.class)
                .eq(Workauthor::getWorkAuthorID, id));
        if (Objects.isNull(workauthor)) {
            throw new BaseException("不存在该关联作者");
        }

        Work work = iWorkService.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID, workauthor.getWorkID()));
        checkRoleUtil.checkPermissionAchievement(work.getStatus());

        baseMapper.deleteById(id);

        //维护AllAuthor字段
        updateAllAuthor(work, workauthor);

        return true;
    }

    /**
     * 修改著作作者
     * @param workauthor 著作作者信息
     * @return 修改操作是否成功
     */
    @Override
    public boolean updateWorkAuthor(Workauthor workauthor) {
        Work work = iWorkService.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID, workauthor.getWorkID()));
        checkRoleUtil.checkPermissionAchievement(work.getStatus());
        double newAssessment;
        try {
            newAssessment = Double.parseDouble(workauthor.getAssessment());
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0 - 100范围内");
        }

        String Pscore = "0.00";

        if(work.getScore()>0){
            float finalValue = work.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }
        List<Workauthor> workauthorList = query().eq("WorkID", workauthor.getWorkID()).list();

        double sum = 0;
        // 只计算已填写考核系数的作者
        for (Workauthor author : workauthorList) {
            if (!author.getWorkAuthorID().equals(workauthor.getWorkAuthorID())) {
                if(!StrUtil.isBlank(author.getAssessment())){
                    sum += Double.parseDouble(author.getAssessment());
                }
            }
        }
        // 检查已填写作者考核系数总和是否超过100
        if (sum + newAssessment > 100) {
            throw new BaseException("已填写作者考核系数总和大于100!");
        }


        workauthor.setPscore(Pscore);

        baseMapper.updateById(workauthor);

        //维护AllAuthor字段
        updateAllAuthor(work, workauthor);

        return true;
    }




    /**
     * 维护AllAuthor字段
     * @param work
     * @param workauthor
     */
    private void updateAllAuthor(Work work, Workauthor workauthor) {
        //维护AllAuthor字段
        //1.先删除原来的AllAuthor字段
        work.setAllauthor(null);
        iWorkService.updateById(work);
        //2.查询该著作的所有作者
        List<Workauthor> allAuthorList = list(Wrappers.lambdaQuery(Workauthor.class)
                .eq(Workauthor::getWorkID, workauthor.getWorkID()));
        //3.按照作者类型排序
        allAuthorList.sort(Comparator.comparingInt(p -> AUTHOR_TYPE_ORDER.indexOf(p.getAuthortype())));
        //4.根据工号集合查询用户的主键id
        List<String> userAccountList = allAuthorList.stream().map(Workauthor::getUserAccount).collect(Collectors.toList());
        List<User> userList = Collections.emptyList();
        if (!userAccountList.isEmpty()) {
            userList = iUserService.list(Wrappers.lambdaQuery(User.class)
                    .in(User::getAccount, userAccountList));
        }
        List<String> uidList = userList.stream().map(User::getUid).collect(Collectors.toList());
        //5.将主键id拼接成字符串
        String allAuthor = String.join(",", uidList);
        //6.更新AllAuthor字段
        work.setAllauthor(allAuthor);
        iWorkService.updateById(work);
    }
}